import {
  useState,
  useRef,
  useEffect,
  useImperativeHandle,
  forwardRef,
} from "react";
import type { ChangeEvent, KeyboardEvent, RefObject } from "react";
import ModelSelector from "./ModelSelector";
import type { AiModelResponse } from "../services/chat/geiAiModel";
import ImageUploader from "./ImageUploader";
import React from "react";
import userService from "../utils/userService"; // 导入userService
import alertService from "../utils/alertService"; // 导入alert服务

// 最大输入字符数限制
const MAX_INPUT_LENGTH = 500;

// 标签样式映射
const tagStyles: Record<
  string,
  { bgColor: string; textColor: string; icon: string }
> = {
  文本对话: {
    bgColor: "bg-green-100 dark:bg-green-900/30",
    textColor: "text-green-800 dark:text-green-300",
    icon: "💬",
  },
  联网: {
    bgColor: "bg-blue-100 dark:bg-blue-900/30",
    textColor: "text-blue-800 dark:text-blue-300",
    icon: "🌐",
  },
  多模态: {
    bgColor: "bg-purple-100 dark:bg-purple-900/30",
    textColor: "text-purple-800 dark:text-purple-300",
    icon: "📊",
  },
  图像分析: {
    bgColor: "bg-pink-100 dark:bg-pink-900/30",
    textColor: "text-pink-800 dark:text-pink-300",
    icon: "🔍",
  },
};

// 定义上传文件类型接口
interface UploadFile {
  id: string; // 唯一ID
  file: File; // 文件对象
  previewUrl?: string; // 预览URL（图片类型）
}

// 定义InputArea组件的ref类型
export interface InputAreaRef {
  // 设置输入框的值
  setInputText: (text: string) => void;
  // 获取输入框的引用
  getTextareaRef: () => RefObject<HTMLTextAreaElement> | null;
  addImageToUploader: (file: any) => void; // 添加处理图片的方法
}

interface InputAreaProps {
  isLoading: boolean;
  onSendMessage: (
    message: string,
    files?: UploadFile[],
    options?: { isWebSearch?: boolean; isDeepThinking?: boolean }
  ) => void;
  onSendWithFiles?: (
    message: string,
    files: UploadFile[],
    options?: { isWebSearch?: boolean; isDeepThinking?: boolean }
  ) => void;
  onFileUpload?: (file: File | File[]) => void;
  models: AiModelResponse[];
  selectedModel: AiModelResponse;
  onModelChange: (model: AiModelResponse) => void;
}

const InputArea = forwardRef<InputAreaRef, InputAreaProps>(
  (
    {
      isLoading,
      onSendMessage,
      onSendWithFiles,
      models,
      selectedModel,
      onModelChange,
    },
    ref
  ) => {
    const [inputValue, setInputValue] = useState<string>("");
    const [isWebSearch, setIsWebSearch] = useState<boolean>(false);
    const [uploadedFiles, setUploadedFiles] = useState<UploadFile[]>([]);
    const [showImageUploader, setShowImageUploader] = useState<boolean>(false);
    const textareaRef = useRef<HTMLTextAreaElement>(null);
    const fileInputRef = useRef<HTMLInputElement>(null);

    // 暴露方法给父组件
    useImperativeHandle(ref, () => ({
      setInputText: (text: string) => {
        setInputValue(text);
        setTimeout(() => {
          if (textareaRef.current) {
            textareaRef.current.focus();
            textareaRef.current.style.height = "auto";
            textareaRef.current.style.height =
              Math.min(Math.max(textareaRef.current.scrollHeight, 150), 150) +
              "px";
          }
        }, 10);
      },
      getTextareaRef: () => textareaRef as RefObject<HTMLTextAreaElement>,
      addImageToUploader: (file: any) => {
        // 检查是否已达到最大图片数量限制
        const maxImages = 5; // 与ImageUploader中保持一致
        if (uploadedFiles.length >= maxImages) {
          alertService.warning(`已达到最大图片数量限制(${maxImages}张)`);
          // 如果有预览URL，清理它
          if (file.previewUrl) {
            URL.revokeObjectURL(file.previewUrl);
          }
          return;
        }

        // 检查是否已经存在相同的图片（基于预览URL或文件名）
        const isDuplicate = uploadedFiles.some((existingFile) => {
          // 对于同名图片进行检查
          if (
            existingFile.file.name === file.file.name &&
            existingFile.file.size === file.file.size
          ) {
            return true;
          }

          // 对于剪贴板图片，检查预览URL和文件大小
          if (
            file.file.name.startsWith("clipboard_image_") &&
            existingFile.file.name.startsWith("clipboard_image_")
          ) {
            // 比较文件大小
            if (existingFile.file.size === file.file.size) {
              return true;
            }

            // 比较预览URL (可能不太可靠，因为每次创建的URL都是唯一的)
            if (existingFile.previewUrl === file.previewUrl) {
              return true;
            }
          }
          return false;
        });

        // 如果是重复图片，显示提示但不添加
        if (isDuplicate) {
          // 如果有预览URL，清理它
          if (file.previewUrl) {
            URL.revokeObjectURL(file.previewUrl);
          }
          return;
        }

        // 添加图片到上传队列
        setUploadedFiles((prevFiles) => [...prevFiles, file]);

        // 确保文件上传器可见
        setShowImageUploader(true);

        // 重新获得焦点
        setTimeout(() => {
          if (textareaRef.current) {
            textareaRef.current.focus();
          }
        }, 100);
      },
    }));

    // 自动聚焦功能
    useEffect(() => {
      if (textareaRef.current) {
        textareaRef.current.focus();
      }
    }, []);

    // 添加输入框value变化监听
    useEffect(() => {
      const textarea = textareaRef.current;
      if (!textarea) return;

      // 使用事件委托监听document上发生的提示词点击事件
      const handleDocumentClick = () => {
        // 短暂延迟，让可能的DOM操作完成
        setTimeout(() => {
          if (textarea && textarea.value !== inputValue) {
            console.log("检测到提示词点击后输入框值变化:", textarea.value);
            setInputValue(textarea.value);
          }
        }, 10);
      };

      // 监听document的点击事件，可能触发提示词
      document.addEventListener("click", handleDocumentClick);

      // 基本事件监听
      const handleInput = () => {
        if (textarea.value !== inputValue) {
          setInputValue(textarea.value);
        }
      };

      textarea.addEventListener("input", handleInput);
      textarea.addEventListener("change", handleInput);

      return () => {
        document.removeEventListener("click", handleDocumentClick);
        textarea.removeEventListener("input", handleInput);
        textarea.removeEventListener("change", handleInput);
      };
    }, [inputValue]);

    // 自动调整高度
    useEffect(() => {
      const textarea = textareaRef.current;
      if (textarea) {
        textarea.style.height = "auto";
        const scrollHeight = textarea.scrollHeight;
        textarea.style.height =
          scrollHeight > 150 ? "150px" : `${scrollHeight}px`;
      }
    }, [inputValue]);

    // 清理预览URL
    useEffect(() => {
      return () => {
        // 组件卸载时，清理预览URL，避免内存泄漏
        uploadedFiles.forEach((file) => {
          if (file.previewUrl) URL.revokeObjectURL(file.previewUrl);
        });
      };
    }, [uploadedFiles]);

    const handleInputChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
      const newValue = e.target.value;

      // 检查输入长度是否超过限制
      if (newValue.length > MAX_INPUT_LENGTH) {
        // 超过限制，截断文本并显示提示
        setInputValue(newValue.substring(0, MAX_INPUT_LENGTH));
        e.target.value = newValue.substring(0, MAX_INPUT_LENGTH);

        // 显示警告消息
        alertService.warning(`输入长度不能超过${MAX_INPUT_LENGTH}个字符`);
        return;
      }

      setInputValue(newValue);
    };

    const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {
      // 检查是否正在使用输入法
      // @ts-expect-error - isComposing 属性在某些浏览器中可用
      if (e.key === "Enter" && !e.shiftKey && !e.isComposing) {
        e.preventDefault();
        handleSendClick();
      }
    };

    // 处理输入法输入完成事件
    const handleCompositionEnd = (
      e: React.CompositionEvent<HTMLTextAreaElement>
    ) => {
      // 输入法输入完成后，更新输入值
      setInputValue(e.currentTarget.value);
    };

    const handleSendClick = () => {
      // 检查输入是否为空且没有上传文件
      const trimmedInput = inputValue.trim();
      if ((!trimmedInput && uploadedFiles.length === 0) || isLoading) {
        return;
      }

      // 如果有上传文件，则使用带有文件的发送方法
      if (uploadedFiles.length > 0 && onSendWithFiles) {
        onSendWithFiles(trimmedInput, uploadedFiles, {
          isWebSearch,
        });
      } else {
        // 否则使用普通发送方法
        onSendMessage(trimmedInput, undefined, {
          isWebSearch,
        });
      }

      // 清空输入和文件
      setInputValue("");
      setUploadedFiles([]);
      setShowImageUploader(false);

      // 重置textarea高度
      if (textareaRef.current) {
        textareaRef.current.value = "";
        textareaRef.current.style.height = "auto";
      }

      // 恢复焦点到输入框
      setTimeout(() => {
        if (textareaRef.current) {
          textareaRef.current.focus();
        }
      }, 0);
    };

    // 处理文件选择
    const handleFileSelect = (e: ChangeEvent<HTMLInputElement>) => {
      const files = e.target.files;
      if (!files || files.length === 0) return;

      // 处理选中的文件
      const filesArray = Array.from(files);

      // 检查文件类型，暂时只支持图片
      const imageFiles = filesArray.filter((file) =>
        file.type.startsWith("image/")
      );

      // 有文件且是图片类型
      if (imageFiles.length > 0) {
        // 检查文件数量限制
        const maxImages = 5; // 与ImageUploader中保持一致
        if (uploadedFiles.length + imageFiles.length > maxImages) {
          console.warn(`超过最大图片数量限制(${maxImages})`);
          // 只取能添加的部分
          const availableSlots = Math.max(0, maxImages - uploadedFiles.length);
          if (availableSlots > 0) {
            handleImagesSelected(imageFiles.slice(0, availableSlots));
          }
        } else {
          // 检查重复文件
          const duplicateFiles = imageFiles.filter((newFile) =>
            uploadedFiles.some(
              (existingFile) =>
                existingFile.file.name === newFile.name &&
                existingFile.file.size === newFile.size &&
                existingFile.file.lastModified === newFile.lastModified
            )
          );

          // 如果存在重复文件，给出提示
          if (duplicateFiles.length > 0) {
            alertService.warning(
              duplicateFiles.length === 1
                ? `文件 "${duplicateFiles[0].name}" 已存在，已跳过添加`
                : `${duplicateFiles.length} 个重复文件已跳过添加`
            );
          }

          const nonDuplicateFiles = imageFiles.filter(
            (newFile) =>
              !uploadedFiles.some(
                (existingFile) =>
                  existingFile.file.name === newFile.name &&
                  existingFile.file.size === newFile.size &&
                  existingFile.file.lastModified === newFile.lastModified
              )
          );

          if (nonDuplicateFiles.length > 0) {
            handleImagesSelected(nonDuplicateFiles);
          }
        }
      }

      // 重置文件输入，以便于可以再次选择相同的文件
      if (fileInputRef.current) {
        fileInputRef.current.value = "";
      }
    };

    // 处理图片选择
    const handleImagesSelected = (files: File[]) => {
      // 如果没有文件，清空上传文件列表
      if (files.length === 0) {
        // 清理所有预览URL以避免内存泄露
        uploadedFiles.forEach((file) => {
          if (file.previewUrl) URL.revokeObjectURL(file.previewUrl);
        });
        setUploadedFiles([]);
        return;
      }

      // 检查是否是删除操作
      // 如果新文件数量少于已有文件，且所有新文件都已存在，则认为是删除操作
      const isDeleteOperation =
        files.length < uploadedFiles.length &&
        files.every((newFile) =>
          uploadedFiles.some(
            (oldFile) =>
              oldFile.file.name === newFile.name &&
              oldFile.file.size === newFile.size &&
              oldFile.file.lastModified === newFile.lastModified
          )
        );

      if (isDeleteOperation) {
        // 找出保留下来的文件
        const updatedFiles = uploadedFiles.filter((oldFile) =>
          files.some(
            (newFile) =>
              oldFile.file.name === newFile.name &&
              oldFile.file.size === newFile.size &&
              oldFile.file.lastModified === newFile.lastModified
          )
        );

        // 清理已被删除文件的预览URL
        uploadedFiles
          .filter((file) => !updatedFiles.includes(file))
          .forEach((file) => {
            if (file.previewUrl) URL.revokeObjectURL(file.previewUrl);
          });

        // 更新上传文件列表
        setUploadedFiles(updatedFiles);
        return;
      }

      // 添加新文件的逻辑
      // 首先过滤掉重复文件
      const nonDuplicateFiles = files.filter(
        (newFile) =>
          !uploadedFiles.some(
            (existingFile) =>
              existingFile.file.name === newFile.name &&
              existingFile.file.size === newFile.size &&
              existingFile.file.lastModified === newFile.lastModified
          )
      );

      if (nonDuplicateFiles.length === 0) {
        // 没有新文件需要添加
        return;
      }

      // 创建新文件的UploadFile对象
      const newFiles: UploadFile[] = nonDuplicateFiles.map((file) => ({
        id: `file_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
        file,
        previewUrl: URL.createObjectURL(file),
      }));

      // 更新上传文件列表，添加新文件
      setUploadedFiles((prevFiles) => [...prevFiles, ...newFiles]);
    };

    // 处理文件按钮点击
    const handleFileButtonClick = () => {
      // 正确的切换逻辑：如果上传器已经显示，则隐藏；如果未显示，则显示
      if (showImageUploader) {
        setShowImageUploader(false); // 隐藏上传器，无论是否有已选图片
      } else {
        setShowImageUploader(true); // 显示上传器
      }
    };

    const toggleWebSearch = () => {
      setIsWebSearch(!isWebSearch);
    };

    /**
     * 检查模型是否支持指定功能
     * @returns 是否支持该功能
     */
    const modelSupportsFeature = (): boolean => {
      // 所有模型都支持所有功能
      return true;
    };

    /**
     * 获取模型支持的标签
     * @returns 标签数组
     */
    const getModelTags = (): string[] => {
      // 返回 tagStyles 中定义的所有标签
      return Object.keys(tagStyles);
    };

    /**
     * 渲染模型标签
     */
    const renderModelTags = () => {
      const tags = getModelTags();

      if (!tags || tags.length === 0) return null;

      return tags.map((tag, index) => {
        const style = tagStyles[tag] || {
          bgColor: "bg-gray-100 dark:bg-gray-700",
          textColor: "text-gray-700 dark:text-gray-300",
          icon: "✓",
        };

        return (
          <span
            key={index}
            className={`inline-flex items-center px-1.5 py-0.5 rounded-full text-xs font-medium ${style.bgColor} ${style.textColor}`}
          >
            <span className="mr-0.5">{style.icon}</span>
            {tag}
          </span>
        );
      });
    };

    return (
      <div className="w-full border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 p-3 pb-4">
        <div className="flex flex-col bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-300 dark:border-gray-600">
          {/* 功能按钮栏 - 改进响应式布局 */}
          <div className="flex flex-wrap items-center px-3 py-1.5 border-b border-gray-200 dark:border-gray-700 gap-2">
            {/* 顶部行：操作按钮和模型选择器 */}
            <div className="flex flex-wrap items-center justify-between w-full gap-2">
              {/* 按钮组和标签 - 修改为同一行显示 */}
              <div className="flex flex-wrap items-center gap-2">
                {/* 仅当模型支持联网功能时显示联网搜索按钮 */}
                {modelSupportsFeature() && (
                  <button
                    onClick={toggleWebSearch}
                    className={`flex items-center px-2 sm:px-3 py-1 rounded-full text-xs sm:text-sm font-medium transition-colors
                      ${
                        isWebSearch
                          ? "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400"
                          : "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"
                      }`}
                  >
                    {/* Internet 网络图标 */}
                    <svg
                      width="18"
                      height="18"
                      viewBox="0 0 20 20"
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                      className="mr-1"
                    >
                      <circle
                        cx="10"
                        cy="10"
                        r="9"
                        stroke="currentColor"
                        strokeWidth="1.8"
                      ></circle>
                      <path
                        d="M10 1c1.657 0 3 4.03 3 9s-1.343 9-3 9M10 19c-1.657 0-3-4.03-3-9s1.343-9 3-9M1 10h18"
                        stroke="currentColor"
                        strokeWidth="1.8"
                      ></path>
                    </svg>
                    <span className="truncate">联网搜索</span>
                  </button>
                )}

                {/* 模型功能标签 - 直接和按钮在同一行 */}
                {renderModelTags()}
              </div>

              {/* 模型选择器 */}
              <div className="flex-shrink-0">
                <ModelSelector
                  selectedModel={selectedModel}
                  models={models}
                  onModelChange={onModelChange}
                />
              </div>
            </div>
          </div>

          {/* 使用自定义图片选择器 */}
          {showImageUploader && userService.isLoggedIn && (
            <div className="w-full mb-2 p-3 bg-white dark:bg-gray-800 rounded-md shadow-sm border border-gray-300 dark:border-gray-600">
              <ImageUploader
                onImagesSelected={handleImagesSelected}
                disabled={isLoading}
                maxImages={5}
                externalSelectedImages={uploadedFiles.map((file) => file.file)}
              />
            </div>
          )}

          {/* 输入区域 */}
          <div className="flex items-end">
            <textarea
              ref={textareaRef}
              value={inputValue}
              onChange={handleInputChange}
              onKeyDown={handleKeyDown}
              onCompositionEnd={handleCompositionEnd}
              placeholder="输入消息..."
              className="flex-1 m-3 mr-0 p-2 resize-none border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400 dark:bg-gray-700 dark:text-white transition-all"
              rows={1}
              disabled={isLoading}
              maxLength={MAX_INPUT_LENGTH}
            ></textarea>
            <div className="flex px-2 items-center">
              {/* 文件上传按钮 - 仅在用户已登录时显示 */}
              {userService.isLoggedIn && (
                <button
                  className="rounded-full p-1.5 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors focus:outline-none focus:ring-1 focus:ring-blue-500 dark:focus:ring-blue-400"
                  onClick={handleFileButtonClick}
                  disabled={isLoading}
                  title="上传图片"
                >
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    className="h-5 w-5"
                    fill="none"
                    viewBox="0 0 24 24"
                    stroke="currentColor"
                  >
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2}
                      d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
                    />
                  </svg>
                </button>
              )}
              {/* 隐藏的文件输入 */}
              <input
                type="file"
                ref={fileInputRef}
                onChange={handleFileSelect}
                className="hidden"
                accept="image/*"
                multiple
              />
              {/* 发送按钮 */}
              <button
                className={`rounded-full p-1.5 ml-1 mr-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:focus:ring-blue-400 ${
                  isLoading
                    ? "text-gray-400 dark:text-gray-600 cursor-not-allowed"
                    : !inputValue.trim() && uploadedFiles.length === 0
                    ? "text-gray-400 dark:text-gray-600 cursor-not-allowed"
                    : "text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300 hover:bg-blue-50 dark:hover:bg-blue-900/20"
                }`}
                onClick={handleSendClick}
                disabled={
                  isLoading ||
                  (!inputValue.trim() && uploadedFiles.length === 0)
                }
                title="发送消息"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  className="h-5 w-5"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2}
                    d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"
                  />
                </svg>
              </button>
            </div>
          </div>

          {/* 显示输入字符计数 */}
          <div className="px-4 pb-2 flex justify-end">
            <span
              className={`text-xs ${
                inputValue.length > MAX_INPUT_LENGTH * 0.9
                  ? "text-red-500 dark:text-red-400"
                  : "text-gray-500 dark:text-gray-400"
              }`}
            >
              {inputValue.length}/{MAX_INPUT_LENGTH}
            </span>
          </div>
        </div>
      </div>
    );
  }
);

export default InputArea;
